package com.example.userservice.service.impl;

import com.example.userservice.common.exception.ServiceException;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.example.userservice.common.constants.JWTConstants;
import com.example.userservice.common.enums.ResultCode;
import com.example.userservice.common.utils.ThreadLocalUtil;
import com.example.userservice.feign.PermissionServiceClient;
import com.example.userservice.mapper.UserMapper;
import com.example.userservice.model.Result;
import com.example.userservice.model.User;
import com.example.userservice.model.dto.*;
import com.example.userservice.model.vo.UserVO;
import com.example.userservice.service.TokenService;
import com.example.userservice.service.UserService;
import com.github.pagehelper.PageHelper;
import io.seata.spring.annotation.GlobalTransactional;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * 功能描述:
 *
 * @author Lenovo
 * @date 2025/6/15
 */
@Slf4j
@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private TokenService tokenService;

    @Autowired
    private PermissionServiceClient permissionServiceClient;

    @Override
    @GlobalTransactional(name = "user-register-tx", rollbackFor = Exception.class)
    public Result<Void> register(UserRegisterDTO userRegisterDTO) {
        // 检查用户名是否已存在
        Long count = userMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, userRegisterDTO.getUsername()));
        if (count > 0) {
            return Result.fail(ResultCode.AILED_USER_EXISTS);
        }
        Long emailCount = userMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getEmail, userRegisterDTO.getEmail()));
        if (emailCount > 0) {
            return Result.fail(ResultCode.EMAIL_EXISTS);
        }
        Long phoneCount = userMapper.selectCount(new LambdaQueryWrapper<User>()
                .eq(User::getPhone, userRegisterDTO.getPhone()));
        if (phoneCount > 0) {
            return Result.fail(ResultCode.PHONE_EXISTS);
        }

        User user = new User();
        BeanUtils.copyProperties(userRegisterDTO, user);

        // 插入用户数据
        int result = userMapper.insert(user);
        if (result != 1) {
            return Result.fail(ResultCode.FAILED);
        }

        Long userId = user.getUserId();
        log.info("用户注册成功，用户ID: {}", userId);

        // 测试开关：模拟失败场景
        if ("test_fail".equals(userRegisterDTO.getUsername())) {
            log.error("触发测试失败场景");
            throw new RuntimeException("测试分布式事务回滚");
        }

        // 调用permission-service绑定默认角色
        Result<Void> rpcResult = permissionServiceClient.bindDefaultRole(userId);
        log.info("绑定默认角色：{}", rpcResult);

        // 检查远程调用结果，如果失败则抛出异常触发回滚
        if (rpcResult.getCode() != 1000) {
            log.error("绑定默认角色失败，触发事务回滚");
            throw new RuntimeException("绑定默认角色失败: " + rpcResult.getMsg());
        }

        return Result.ok();
    }

    @Override
    public Result<String> login(UserLoginDTO userLoginDTO) {
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, userLoginDTO.getUsername()));
        //校验用户是否存在
        if (user == null) {
            return Result.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        } else {
            String userPassword = user.getPassword();
            //校验密码
            if (!userPassword.equals(userLoginDTO.getPassword())) {
                return Result.fail(ResultCode.FAILED_LOGIN);
            }
        }
        String token = tokenService.createToken(user.getUserId(), JWTConstants.SECRET,
                user.getUsername(),user.getPhone());
        return Result.ok(token);
    }

    @Override
    public Result<Void> resetPassword(PasswordResetDTO passwordResetDTO) {
        // 获取当前登录用户ID
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
        String currentUserRole = getCurrentUserRole(currentUserId);
        // 检查目标用户是否存在
        User targetUser = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, passwordResetDTO.getUsername()));
        if (targetUser == null) {
            return Result.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }

        // 获取目标用户角色
        Result<String> targetRoleResult = permissionServiceClient.getUserRoleCode(targetUser.getUserId());
        if (targetRoleResult.getCode() != 1000) {
            return Result.fail(ResultCode.FAILED_GET_ROLE);
        }
        String targetRole = targetRoleResult.getData();

        // 权限控制：判断是否能重置目标用户密码
        if (!canOperationUser(currentUserRole, targetRole, currentUserId, targetUser.getUserId())) {
            return Result.fail(ResultCode.FAILED_AUTHORITY);
        }

        // 更新密码
        User updateUser = new User();
        updateUser.setUserId(targetUser.getUserId());
        updateUser.setPassword(passwordResetDTO.getNewPassword());

        int result = userMapper.updateById(updateUser);
        if (result != 1) {
            return Result.fail(ResultCode.FAILED);
        }

        return Result.ok();
    }

    private String getCurrentUserRole(Long currentUserId) {
        // 获取当前用户的角色
        Result<String> roleResult = permissionServiceClient.getUserRoleCode(currentUserId);
        if (roleResult.getCode() != 1000) {
            throw new ServiceException(ResultCode.FAILED_GET_ROLE);
        }
        return roleResult.getData();
    }

    @Override
    public Result<List<UserVO>> getUserList(UserPageQueryDTO userPageQueryDTO) {
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
        String currentUserRole = getCurrentUserRole(currentUserId);
        // 开启分页
        PageHelper.startPage(userPageQueryDTO.getPageNum(), userPageQueryDTO.getPageSize());

        List<UserVO> userVOList;

        if ("super_admin".equals(currentUserRole)) {
            // 超管可以查看所有用户
            userVOList = userMapper.selectUserListWithRole();
        } else if ("admin".equals(currentUserRole)) {
            // 管理员可以查看所有用户，但需要过滤掉超管
            userVOList = userMapper.selectUserListWithRole();
            // 过滤掉超管用户
            userVOList = filterSuperAdminUsers(userVOList);
        } else if ("user".equals(currentUserRole)) {
            // 普通用户只能查看自己
            userVOList = userMapper.selectUserById(currentUserId);
        } else {
            // 未知角色，拒绝访问
            return Result.fail(ResultCode.FAILED_AUTHORITY);
        }

        return Result.ok(userVOList);
    }

    /**
     * 过滤掉超管和管理员用户
     */
    private List<UserVO> filterSuperAdminUsers(List<UserVO> userVOList) {
        return userVOList.stream()
                .filter(userVO -> {
                    // 获取用户角色
                    Result<String> roleResult = permissionServiceClient.getUserRoleCode(userVO.getUserId());
                    if (roleResult.getCode() == 1000) {
                        String role = roleResult.getData();
                        return !"super_admin".equals(role) && !"admin".equals(role);
                    }
                    return true; // 如果获取角色失败，保留该用户
                }).collect(Collectors.toList());
    }

    @Override
    public Result<UserVO> getUserDetail(Long userId) {
        // 获取当前登录用户ID
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);
        // 获取当前用户的角色
        log.info("获取到ThreadLocalUtil中的userId:{}",currentUserId);
        Result<String> roleResult = permissionServiceClient.getUserRoleCode(currentUserId);
        if (roleResult.getCode() != 1000) {
            return Result.fail(ResultCode.FAILED_GET_ROLE);
        }
        String currentUserRole = roleResult.getData();
        // 查询目标用户
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserId, userId));
        if (user == null) {
            return Result.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }
        // 获取目标用户角色
        Result<String> targetRole = permissionServiceClient.getUserRoleCode(user.getUserId());
        if (targetRole.getCode() != 1000) {
            return Result.fail(ResultCode.FAILED_GET_ROLE);
        }
        // 判断是否能查看目标用户信息
        if (!canOperationUser(currentUserRole, targetRole.getData(), currentUserId, userId)) {
            return Result.fail(ResultCode.FAILED_AUTHORITY);
        }
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return Result.ok(userVO);
    }

    @Override
    public Result<Void> updateUser(Long userId, UserUpdateDTO userUpdateDTO) {
        // 获取当前登录用户ID
        Long currentUserId = ThreadLocalUtil.get("userId", Long.class);

        // 获取当前用户的角色
        Result<String> roleResult = permissionServiceClient.getUserRoleCode(currentUserId);
        if (roleResult.getCode() != 1000) {
            return Result.fail(ResultCode.FAILED_GET_ROLE);
        }
        String currentUserRole = roleResult.getData();

        // 查询目标用户
        User targetUser = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUserId, userId));
        if (targetUser == null) {
            return Result.fail(ResultCode.FAILED_USER_NOT_EXISTS);
        }

        // 获取目标用户角色
        Result<String> targetRoleResult = permissionServiceClient.getUserRoleCode(userId);
        if (targetRoleResult.getCode() != 1000) {
            return Result.fail(ResultCode.FAILED_GET_ROLE);
        }
        String targetRole = targetRoleResult.getData();

        // 权限控制：判断是否能修改目标用户信息
        if (!canOperationUser(currentUserRole, targetRole, currentUserId, userId)) {
            return Result.fail(ResultCode.FAILED_AUTHORITY);
        }
        User user = userMapper.selectOne(new LambdaQueryWrapper<User>()
                .eq(User::getUsername, userUpdateDTO.getUsername())
                .ne(User::getUserId, userId));
        // 检查用户名是否已被其他用户使用
        if (user != null) {
            return Result.fail(ResultCode.AILED_USER_EXISTS);
        }

        // 检查邮箱是否已被其他用户使用
        if (userUpdateDTO.getEmail() != null && !userUpdateDTO.getEmail().equals(targetUser.getEmail())) {
            Long emailCount = userMapper.selectCount(new LambdaQueryWrapper<User>()
                    .eq(User::getEmail, userUpdateDTO.getEmail())
                    .ne(User::getUserId, userId));
            if (emailCount > 0) {
                return Result.fail(ResultCode.EMAIL_EXISTS);
            }
        }

        // 检查手机号是否已被其他用户使用
        if (userUpdateDTO.getPhone() != null && !userUpdateDTO.getPhone().equals(targetUser.getPhone())) {
            Long phoneCount = userMapper.selectCount(new LambdaQueryWrapper<User>()
                    .eq(User::getPhone, userUpdateDTO.getPhone())
                    .ne(User::getUserId, userId));
            if (phoneCount > 0) {
                return Result.fail(ResultCode.PHONE_EXISTS);
            }
        }

        // 更新用户信息
        User updateUser = new User();
        updateUser.setUserId(userId);
        if (userUpdateDTO.getUsername() != null) {
            updateUser.setUsername(userUpdateDTO.getUsername());
        }
        if (userUpdateDTO.getEmail() != null) {
            updateUser.setEmail(userUpdateDTO.getEmail());
        }
        if (userUpdateDTO.getPhone() != null) {
            updateUser.setPhone(userUpdateDTO.getPhone());
        }
        if (userUpdateDTO.getPassword() != null) {
            updateUser.setPassword(userUpdateDTO.getPassword());
        }

        int result = userMapper.updateById(updateUser);
        if (result != 1) {
            return Result.fail(ResultCode.FAILED);
        }

        return Result.ok();
    }

    private boolean canOperationUser(String currentRole, String targetRole,
                                     Long currentUserId, Long userId) {
        // admin不能查看super_admin
        if ("admin".equals(currentRole) && "super_admin".equals(targetRole)) {
            return false;
        }
        // user只能查看自己
        if ("user".equals(currentRole)) {
            return currentUserId.equals(userId);
        }
        return true;
    }
}
